//
//  BluetoothManager.m
//  bluetooth
//
//  Created by jacky on 2021/8/10.
//
#import "BluetoothManager.h"

static const NSInteger timeout = 30;

@interface BluetoothManager()<CBCentralManagerDelegate,CBPeripheralDelegate>

@property (nonatomic, strong) CBCentralManager *centralManager;

@property (nonatomic, strong) CBPeripheral *peripheral;

@property (nonatomic, strong) NSMutableArray *peripheralArr;

@property (nonatomic, strong) CBPeripheralManager *peripheralManager;

@property (nonatomic, copy) NSString *autoName;

///0-未连接；1-正在连接；2-已连接； 3-断开连接; 4-连接失败；5-连接超时；6-蓝牙未开启; 7-蓝牙权限未开启;
@property (nonatomic, assign) NSInteger status;

@property (nonatomic, strong) dispatch_source_t timer;


@end

@implementation BluetoothManager


+ (instancetype)sharedInstance {
    static BluetoothManager *_sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}

- (instancetype)init {
    if (self = [super init]) {
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue() options:@{CBCentralManagerOptionShowPowerAlertKey:@(NO)}];
        _peripheralArr = [[NSMutableArray alloc] init];
        _status = 0;
    }
    return self;
}

- (void)startTimer {
    if (_timer != nil) {
        return;
    }
    __block NSInteger second = timeout;
    __weak typeof(self) weakSelf = self;
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, quene);
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (second == 0) {
                [weakSelf.centralManager stopScan];
                weakSelf.status = 5;
                [weakSelf.delegate didUpdateState:5];
                weakSelf.timer = nil;
            }
            second--;
        });
    });
    dispatch_resume(timer);
    _timer = timer;
}

#pragma mark - CBCentralManagerDelegate

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {

    switch (central.state) {
        case CBManagerStatePoweredOn:
//            NSLog(@"蓝牙开启且可用");
        {
            _status = 0;
            [_delegate didUpdateState:_status];;
            if (_autoName.length > 0) {
                [_centralManager scanForPeripheralsWithServices:nil options:nil];
                [self startTimer];
            }
        }
            break;
        case CBManagerStateUnknown:
//            NSLog(@"手机没有识别到蓝牙，请检查手机。");
            break;
        case CBManagerStateResetting:
//            NSLog(@"手机蓝牙已断开连接，重置中。");
            break;
        case CBManagerStateUnsupported:
//            NSLog(@"手机不支持蓝牙功能，请更换手机。");
            break;
        case CBManagerStatePoweredOff:
//            NSLog(@"手机蓝牙功能关闭，请前往设置打开蓝牙及控制中心打开蓝牙。");
            _status = 6;
            [_delegate didUpdateState:_status];
            break;
        case CBManagerStateUnauthorized:
//            NSLog(@"手机蓝牙功能没有权限，请前往设置。");
            _status = 7;
            [_delegate didUpdateState:_status];
            break;
        default:  break;
    }
}

///找到外设
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    if ([_autoName isEqualToString:peripheral.name]) {
        _status = 1;
        [_delegate didUpdateState:_status];
        [_centralManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
    }
    if ([_delegate respondsToSelector:@selector(didDiscoverPeripheral:advertisementData:RSSI:)] && peripheral.name.length > 0) {
        [_peripheralArr addObject:peripheral];
        [_delegate didDiscoverPeripheral:peripheral advertisementData:advertisementData RSSI:RSSI];
      }
}

///连接外设成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    _peripheral = peripheral;
    _status = 2;
    [_delegate didUpdateState:_status];
    if ([_delegate respondsToSelector:@selector(didConnectPeripheral:)]) {
        [_delegate didConnectPeripheral:peripheral];
    }
    [_centralManager stopScan];
    peripheral.delegate = self;
    [peripheral discoverServices:nil];
    if (self.timer != nil) {
        dispatch_source_cancel(self.timer);
        self.timer = nil;
    }
}

///连接外设失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    _peripheral = nil;
    if ([_delegate respondsToSelector:@selector(didFailToConnectPeripheral:error:)]) {
        [_delegate didFailToConnectPeripheral:peripheral error:error];
    }
    _status = 4;
    [_delegate didUpdateState:_status];
    if (self.timer != nil) {
        dispatch_source_cancel(self.timer);
        self.timer = nil;
    }
}

///外设断开了
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    _peripheral = nil;
    _status = 3;
    [_delegate didUpdateState:_status];
    if ([_delegate respondsToSelector:@selector(didDisconnectPeripheral:error:)]) {
        [_delegate didDisconnectPeripheral:peripheral error:error];
    }
}

#pragma mark - CBPeripheralDelegate
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error {
    if ([_delegate respondsToSelector:@selector(didDiscoverServices:)]) {
        [_delegate didDiscoverServices:error];
    }
    for (CBService *service in _peripheral.services) {
        [_peripheral discoverCharacteristics:nil forService:service];
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    if ([_delegate respondsToSelector:@selector(didDiscoverCharacteristicsForService:error:)]) {
        [_delegate didDiscoverCharacteristicsForService:service error:error];
    }
    for(int i = 0; i < service.characteristics.count; i++) {
        CBCharacteristic *c = [service.characteristics objectAtIndex:i];
        if ([[c UUID] isEqual:[CBUUID UUIDWithString:@"2AA1"]]) {
            [_peripheral setNotifyValue:YES forCharacteristic:c];
        }
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if ([_delegate respondsToSelector:@selector(didUpdateValueForCharacteristic:error:)]) {
        [_delegate didUpdateValueForCharacteristic:characteristic error:error];
    }
}


#pragma mark - BluetoothManagerMethonds
///开启扫码
- (bool)start {
    _autoName = @"";
    _status = 0;
    [_delegate didUpdateState:_status];;
    [_peripheralArr removeAllObjects];
    [_centralManager scanForPeripheralsWithServices:nil options:nil];
    return TRUE;
}


///关闭扫描
- (void)stop {
    [_centralManager stopScan];
    if(self.timer) {
        dispatch_source_cancel(self.timer);
    }
    self.timer = nil;
}

///连接设备
- (void)connectPeripheral:(NSString *)name {
    _status = 1;
    [_delegate didUpdateState:_status];
    for (CBPeripheral *peripheral in _peripheralArr) {
        if ([peripheral.name isEqualToString:name]) {
            [_centralManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
        }
    }
}

//通过名称自动连接
- (void)startWithAutoConnect:(NSString *)name {
    _autoName = name;
    if (_status == 6 || _status == 7 || _status == 2 || _status == 1) {
        return;
    }
    _status = 0;
    [_delegate didUpdateState:_status];
    [_peripheralArr removeAllObjects];
    [_centralManager scanForPeripheralsWithServices:nil options:nil];
    [self startTimer];
}

- (void)restarScan {
    _status = 0;
    [_delegate didUpdateState:_status];;
    [_centralManager scanForPeripheralsWithServices:nil options:nil];
    [self startTimer];
}

- (NSInteger)getStatus {
    return _status;
}

@end
